package org.zbclan.bf2.rcon.home.client.ui;

import net.customware.gwt.dispatch.client.DispatchAsync;
import net.customware.gwt.presenter.client.DisplayCallback;
import net.customware.gwt.presenter.client.EventBus;
import net.customware.gwt.presenter.client.place.Place;
import net.customware.gwt.presenter.client.place.PlaceChangedEvent;
import net.customware.gwt.presenter.client.place.PlaceRequest;
import net.customware.gwt.presenter.client.place.PlaceRequestEvent;
import net.customware.gwt.presenter.client.widget.WidgetPresenter;

import org.zbclan.bf2.rcon.common.client.event.GPOSelectedEvent;
import org.zbclan.bf2.rcon.common.client.event.GPOSelectedEventHandler;
import org.zbclan.bf2.rcon.home.client.event.GameModeListReadyEvent;
import org.zbclan.bf2.rcon.home.client.event.GameModeListReadyEventHandler;
import org.zbclan.bf2.rcon.home.client.event.LevelNameListReadyEvent;
import org.zbclan.bf2.rcon.home.client.event.LevelNameListReadyEventHandler;
import org.zbclan.bf2.rcon.home.client.gpo.GPOPresenter;
import org.zbclan.bf2.rcon.home.shared.GetGameModeListCommand;
import org.zbclan.bf2.rcon.home.shared.GetGameModeListResult;
import org.zbclan.bf2.rcon.home.shared.GetLevelNameListCommand;
import org.zbclan.bf2.rcon.home.shared.GetLevelNameListResult;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.inject.Inject;

public class HomePresenter extends WidgetPresenter<HomeDisplay> {

	public static final Place PLACE = new Place("");

	private String name;

	private DispatchAsync dispatcher;

	@Inject
	public HomePresenter(HomeDisplay display, EventBus eventBus,
			DispatchAsync dispatcher) {

		super(display, eventBus);

		this.dispatcher = dispatcher;

		return;
	}

	@Override
	public Place getPlace() {
		return PLACE;
	}

	@Override
	protected void onBind() {

		eventBus.addHandler(LevelNameListReadyEvent.TYPE,
				new LevelNameListReadyEventHandler() {

					public void onLevelNameListReady(String[] names) {
						bindLevelNameClickHandlers(names);
					}
				});

		eventBus.addHandler(GameModeListReadyEvent.TYPE,
				new GameModeListReadyEventHandler() {

					public void onGameModeListReady(String[] sizes) {
						bindGameModeClickHandlers(sizes);
					}
				});

		eventBus.addHandler(GPOSelectedEvent.TYPE,
				new GPOSelectedEventHandler() {

					public void onGPOSelected(String name, String mode) {
						/*
						 * TODO open level by size
						 */
						// Window.alert("TODO open level " + name + " " + mode);
						// Window.open(GWT.getHostPageBaseURL() + "gpo.html"
						// + Location.getQueryString(), "_self", null);
						PlaceRequest request = new PlaceRequest(
								GPOPresenter.PLACE).with("name", name).with(
								"mode", mode);
						eventBus.fireEvent(new PlaceRequestEvent(request));
					}
				});

		return;
	}

	private void bindLevelNameClickHandlers(String[] names) {

		HasClickHandlers[] levelNameClickables = display
				.getLevelNameClickables();
		for (int i = 0; i < levelNameClickables.length; i++) {
			HasClickHandlers c = levelNameClickables[i];
			final String name = names[i];
			c.addClickHandler(new ClickHandler() {

				public void onClick(ClickEvent event) {

					HomePresenter.this.name = name;

					display.showGameModeListDialog(name);

					buildGameModeList(name);

					return;
				}

			});
		}

		return;
	}

	private void buildGameModeList(final String name) {
		// Window.alert("buildGameModeList");

		GameModeListCommand(name);
		// GameModeListHttp(name);

		/*
		 * XXX
		 */
		// String xslUrl = CommonBundle.INSTANCE.levelInfoXsl().getText();
		// String xmlUrl = GWT.getModuleBaseURL() + "../info?name=" + name;
		// GameModeListXslt(xslUrl, xmlUrl);

		return;
	}

	// /**
	// * XXX conflict possibly with gwt -- will
	// *
	// * @param xsl
	// * @param xmlUrl
	// */
	// private native void GameModeListXslt(String xsl, String xmlUrl)/*-{
	// var instance = this;
	//
	// var a = $wnd.$().xslt({
	// "xmlUrl": xmlUrl,
	// "xsl": xsl,
	// "callback": function(data){
	// instance.@org.zbclan.bf2.rcon.home.client.ui.HomePresenter::xsltCallback(Lorg/zbclan/bf2/rcon/home/client/json/InfoJson;)
	// }
	// });
	//
	// return;
	// }-*/;
	//
	// @SuppressWarnings("unused")
	// private void xsltCallback(JavaScriptObject data) {
	// Window.alert("xslt complete");
	// }
	// @SuppressWarnings("unused")
	// private void xsltCallback(InfoJson data) {
	// // Window.alert("xslt complete with gsid = " + data.getMap().getGsid());
	// }

	// /**
	// * @deprecated
	// * @param name
	// */
	// private void GameModeListHttp(String name) {
	//
	// String url = GWT.getModuleBaseURL() + "../info?name=" + name;
	// RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, URL
	// .encode(url));
	//
	// try {
	// Request request = builder.sendRequest(null, new RequestCallback() {
	//
	// public void onError(Request request, Throwable exception) {
	// // Couldn't connect to server (could be timeout, SOP
	// // violation, etc.)
	// }
	//
	// public void onResponseReceived(Request request,
	// Response response) {
	// if (200 == response.getStatusCode()) {
	// // Process the response in response.getText()
	// String desc = response.getText();
	// // parse(desc);
	// InfoJson info = InfoJson.fromString(desc);
	// // Window.alert(info.getMap().getGsid());
	//
	// ArrayList<String> sizeList = new ArrayList<String>();
	// JsArray<Mode> modes = info.getMap().getModes();
	// for (int i = 0; i < modes.length(); i++) {
	// Mode mode = modes.get(i);
	// if ("gpm_cq".equals(mode.getMode())) {
	// JsArray<MapType> mapTypes = mode.getMapTypes();
	// for (int j = 0; j < mapTypes.length(); j++) {
	// sizeList.add(mapTypes.get(j).getPlayers());
	// }
	// }
	// }
	// String[] sizes = new String[sizeList.size()];
	// display.updateSizeSelectionDialog(sizeList
	// .toArray(sizes));
	// eventBus.fireEvent(new GameModeListReadyEvent(sizes));
	//
	// } else {
	// // Handle the error. Can get the status text from
	// // response.getStatusText()
	// }
	// }
	// });
	// } catch (RequestException e) {
	// // Couldn't connect to server
	// }
	// }

	private void GameModeListCommand(final String name) {

		GetGameModeListCommand cmd = new GetGameModeListCommand();
		cmd.setName(name);

		DisplayCallback<GetGameModeListResult> callback = new DisplayCallback<GetGameModeListResult>(
				display) {

			@Override
			protected void handleFailure(Throwable e) {
				// TODO Auto-generated method stub

			}

			@Override
			protected void handleSuccess(GetGameModeListResult value) {
				String[] modes = value.getModes();
				display.updateSizeSelectionDialog(modes);
				eventBus.fireEvent(new GameModeListReadyEvent(modes));
			}
		};

		dispatcher.execute(cmd, callback);
		// Window.alert(GWT.getHostPageBaseURL());
		// Window.alert(GWT.getModuleBaseURL());
	}

	// /**
	// * @deprecated
	// * @param desc
	// */
	// private void parse(String desc) {
	//
	// Window.alert(desc);
	// // try {
	// // // parse the XML document into a DOM
	// // Document doc = XMLParser.parse(desc);
	// //
	// // String name = doc.getElementsByTagName("name").item(0)
	// // .getFirstChild().getNodeValue();
	// //
	// // NodeList modeList = doc.getElementsByTagName("mode");
	// // for (int i=0;i<modeList.getLength();i++){
	// // Element modeElement = (Element) modeList.item(i);
	// // String type = modeElement.getAttribute("type");
	// //
	// // }
	// //
	// // } catch (DOMException e) {
	// // Window.alert("Could not parse XML document.");
	// // }
	//
	// // XsltProcessor processor = new XsltProcessor();
	// // try {
	// // processor.importStyleSheet(CommonBundle.INSTANCE.levelInfoXsl()
	// // .getText());
	// // // processor.setParameter(paramNameString, paramValueString);
	// //
	// // processor.importSource(desc);
	// // String resultString = processor.transform();
	// // Window.alert(resultString);
	// // } catch (XsltProcessingException e) {
	// // Window.alert(e.getMessage());
	// // }
	//
	// return;
	// }

	private void bindGameModeClickHandlers(String[] modes) {

		HasClickHandlers[] GameModeClickables = display.getGameModeClickables();
		for (int i = 0; i < GameModeClickables.length; i++) {
			HasClickHandlers c = GameModeClickables[i];
			final String mode = modes[i];
			c.addClickHandler(new ClickHandler() {

				public void onClick(ClickEvent event) {
					display.hideGameModeDialog();
					eventBus.fireEvent(new GPOSelectedEvent(name, mode));
				}
			});
		}

		return;
	}

	@Override
	protected void onPlaceRequest(PlaceRequest request) {

		eventBus.fireEvent(new PlaceChangedEvent(request));

		refreshDisplay();

		RootLayoutPanel root = RootLayoutPanel.get();
		root.clear();
		root.add(getDisplay().asWidget());

		return;
	}

	@Override
	protected void onUnbind() {
	}

	public void refreshDisplay() {

		dispatcher.execute(new GetLevelNameListCommand(),
				new DisplayCallback<GetLevelNameListResult>(display) {

					@Override
					protected void handleFailure(Throwable e) {
						Window.alert("failed to get level name list "
								+ "due to exception " + e.getMessage());
					}

					@Override
					protected void handleSuccess(GetLevelNameListResult value) {
						String[] names = value.getNames();
						display.showLevelNameList(names);
						eventBus.fireEvent(new LevelNameListReadyEvent(names));
					}
				});

		return;
	}

	public void revealDisplay() {
	}

}
